/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef OLA_COAP_DEF_H
#define OLA_COAP_DEF_H

#include "ola_sdk_api.h"

#ifdef __cplusplus
extern "C" {
#endif

#define OLA_COAP_OPTION_MAX_NUM     16
#define OLA_COAP_UDP_HEADER_LEN     4
#define OLA_COAP_TCP_HEADER_MAX_LEN 14
#define OLA_COAP_TCP_HEADER_MIN_LEN 2
#define OLA_COAP_VERSION            1
#define OLA_COAP_TOKEN_MAX_LEN      8
#define OLA_COAP_URI_MAX_LEN        64

/* COAP over TCP报文判断长度至少需要开头1字节，最多需要5字节 */
#define OLA_COAP_GET_TCP_PACKET_SIZE_MIN_BYTES  1
#define OLA_COAP_GET_TCP_PACKET_SIZE_MAX_BYTES  5

#define OLA_COAP_EXTEND_DELTA_VALUE_UINT8   13
#define OLA_COAP_EXTEND_DELTA_VALUE_UINT16  14
#define OLA_COAP_EXTEND_DELTA_VALUE_UINT32  15
#define OLA_COAP_DELTA_UINT8_ADD_NUM        13
#define OLA_COAP_DELTA_UINT16_ADD_NUM       269
#define OLA_COAP_DELTA_UINT32_ADD_NUM       65805

/* 消息码格式 |<- 3bit 类型 ->|<- 5bit 码值 ->| */
#define OLA_COAP_RESPONSE_CODE(N) (((N) / 100 << 5) | (N) % 100)

typedef enum {
    OLA_COAP_RESPONSE_CODE_CONTENT                      = OLA_COAP_RESPONSE_CODE(205),
    OLA_COAP_RESPONSE_CODE_BAD_REQUEST                  = OLA_COAP_RESPONSE_CODE(400),
    OLA_COAP_RESPONSE_CODE_BAD_OPTION                   = OLA_COAP_RESPONSE_CODE(402),
    OLA_COAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT   = OLA_COAP_RESPONSE_CODE(415),
    OLA_COAP_RESPONSE_CODE_INTERNAL_ERROR               = OLA_COAP_RESPONSE_CODE(500),
    OLA_COAP_RESPONSE_CODE_NOT_IMPLEMENTED              = OLA_COAP_RESPONSE_CODE(501),
    OLA_COAP_RESPONSE_CODE_BAD_GATEWAY                  = OLA_COAP_RESPONSE_CODE(502),
} OlaCoapResponseCode;

typedef enum {
    OLA_COAP_FRAME_TYPE_UNRELIABLE,
    OLA_COAP_FRAME_TYPE_RELIABLE
} OlaCoapFrameType;

/* 消息方法类型 */
typedef enum {
    OLA_COAP_METHOD_TYPE_GET    = 1,
    OLA_COAP_METHOD_TYPE_POST   = 2,
    OLA_COAP_METHOD_TYPE_PUT    = 3,
    OLA_COAP_METHOD_TYPE_DELETE = 4,
} OlaCoapMethodType;

/* 消息类型 */
typedef enum {
    OLA_COAP_MSG_TYPE_CON = 0,
    OLA_COAP_MSG_TYPE_NCON = 1,
    OLA_COAP_MSG_TYPE_ACK = 2,
    OLA_COAP_MSG_TYPE_RESET = 3
} OlaCoapMsgType;

typedef enum {
    OLA_COAP_OPTION_TYPE_TYPE_IF_MATCH      = 1,
    OLA_COAP_OPTION_TYPE_URI_HOST           = 3,
    OLA_COAP_OPTION_TYPE_ETAG               = 4,
    OLA_COAP_OPTION_TYPE_IF_NONE_MATCH      = 5,
    OLA_COAP_OPTION_TYPE_OBSERVE            = 6,
    OLA_COAP_OPTION_TYPE_URI_PORT           = 7,
    OLA_COAP_OPTION_TYPE_LOCATION_PATH      = 8,
    OLA_COAP_OPTION_TYPE_URI_PATH           = 11,
    OLA_COAP_OPTION_TYPE_CONTENT_FORMAT     = 12,
    OLA_COAP_OPTION_TYPE_MAX_AGE            = 14,
    OLA_COAP_OPTION_TYPE_URI_QUERY          = 15,
    OLA_COAP_OPTION_TYPE_ACCEPT             = 17,
    OLA_COAP_OPTION_TYPE_LOCATION_QUERY     = 20,
    OLA_COAP_OPTION_TYPE_PROXY_URI          = 35,
    OLA_COAP_OPTION_TYPE_PROXY_SCHEME       = 39,
    OLA_COAP_OPTION_TYPE_SESSION_ID         = 2048,
    OLA_COAP_OPTION_TYPE_ACCESS_TOKEN_ID    = 2049,
    OLA_COAP_OPTION_TYPE_REQ_ID             = 2050,
    OLA_COAP_OPTION_TYPE_DEV_ID             = 2051,
    OLA_COAP_OPTION_TYPE_USER_ID            = 2052,
    OLA_COAP_OPTION_TYPE_SEQ_NUM_ID         = 2053,
    OLA_COAP_OPTION_TYPE_PUUID              = 2056,
    OLA_COAP_OPTION_TYPE_PLUGIN             = 2057,
    OLA_COAP_OPTION_TYPE_LOCAL_ERR          = 2058,
} OlaCoapOptionType;

/* CoAP消息头 */
typedef struct {
    unsigned int ver : 2;
    unsigned int type : 2;
    unsigned int len;
    unsigned int tokenLen : 4;
    unsigned int code : 8;
    unsigned short msgId;
} OlaCoapHeader;

typedef struct {
    unsigned short option;
    OlaData buf;
} OlaCoapOption;

/* CoAP报文结构 */
typedef struct {
    OlaCoapFrameType type;
    OlaCoapHeader header;
    OlaData token;
    unsigned char optionsNum;
    OlaCoapOption options[OLA_COAP_OPTION_MAX_NUM];
    OlaData payload;
} OlaCoapPacket;

#ifdef __cplusplus
}
#endif

#endif /* OLA_COAP_DEF_H */